package cn.com.zzl.util;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Description：cookie工具类，使用cookie实现浏览历史记录
 * Created by 朱正磊 on 2017-09-16 14:37.
 */
public class CookieUtil {

	/**
	 * @Desc cookie的存活时间（14天）
	 */
	private static final Integer COOKIE_LIFE_TIME = 14 * 24 * 60 * 60;

	/**
	 * @Desc 获得指定cookie中的值（多个子字符串使用,进行拼接的父字符串）
	 * @param request 请求对象
	 * @param cookieName 要查找的cookie的名字
	 * @return 返回指定cookie中的字符串值
	 */
	public static String getCookieValues(HttpServletRequest request, String cookieName) {
		Cookie[] cookies = request.getCookies();
		String cookieValues = null;
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if (cookieName.equals(cookie.getName())) {
					cookieValues = cookie.getValue();
					break;
				}
			}
		}
		return cookieValues;
	}

	/**
	 * @Desc 设置指定cookie中的值，其实这里是新增记录值到原有的记录值上面
	 * 1、得到原先cookie中的值 2、重新设置cookie中的值 3、保存重置后的cookie
	 * @param request 请求对象
	 * @param response 响应对象
	 * @param cookieName 要设置的cookie的名字
	 * @param cookieValue 要添加到浏览历史记录中的字符串
	 * @param historyCount 总共可以显示的历史记录条数
	 */
	public static void setCookie(HttpServletRequest request, HttpServletResponse response,
								 String cookieName, String cookieValue, Integer historyCount) {
		//1、得到原先cookie中的值
		String cookieValues = getCookieValues(request, cookieName);
		//2、重新设置cookie中的值
		setValue(cookieValues, cookieValue, historyCount);
		//3、保存重置后的cookie的值
		saveCookie(request, response, cookieName, cookieValues);
	}

	/**
	 * @Desc 设置浏览历史字符串，将新的子字符串拼接到原字符串的最前面使用,相隔
	 * @param cookieValues 原父字符串
	 * @param cookieValue 新子字符串
	 * @param historyCount 总共可以显示的历史记录条数
	 * @return 返回修改后的字符串
	 */
	public static String setValue(String cookieValues, String cookieValue, Integer historyCount) {
		StringBuilder stringBuilder = new StringBuilder();
		if (cookieValues == null) {
			stringBuilder.append(cookieValue);
		} else {
			List<String> list = Arrays.asList(cookieValues.split(","));
			//使用LinkedList进行插入删除操作
			LinkedList<String> idsList = new LinkedList<String>(list);
			if (!idsList.contains(cookieValue)) {//未浏览过的记录
				if (idsList.size() < historyCount) {
					idsList.addFirst(cookieValue);
				} else {
					idsList.removeLast();
					idsList.addFirst(cookieValue);
				}
			} else {//已浏览过的记录
				idsList.remove(cookieValue);
				idsList.addFirst(cookieValue);
			}
			for (String id : idsList) {
				stringBuilder.append(id).append(",");
			}
			if (stringBuilder.length() > 0) {
				stringBuilder.deleteCharAt(stringBuilder.length() - 1);
			}
		}
		return stringBuilder.toString();
	}

	/**
	 * @Desc 保存cookie的值（设置默认存活时间）
	 * @param request 请求对象
	 * @param response 响应对象
	 * @param cookieName 要保存的cookie的名字
	 * @param cookieValues 保存到cookie中的值
	 */
	public static void saveCookie(HttpServletRequest request, HttpServletResponse response,
								  String cookieName, String cookieValues) {
		saveCookie(request, response, cookieName, cookieValues, COOKIE_LIFE_TIME);
	}

	/**
	 * @Desc 删除指定的cookie
	 * @param request 请求对象
	 * @param response 响应对象
	 * @param cookieName 要删除的cookie的名字
	 */
	public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
		//我们将cookie的值设置为空字符串，存活时间设置为0，然后再保存，其实就是相当于删除cookie
		saveCookie(request, response, cookieName, "", 0);
	}

	/**
	 * @Desc 保存cookie的值并设置cookie的存活时间
	 * @param request 请求对象
	 * @param response 响应对象
	 * @param cookieName 要保存的cookie的名字
	 * @param cookieValues 保存到cookie中的值
	 * @param cookieLifeTime cookie存活时间
	 */
	public static void saveCookie(HttpServletRequest request, HttpServletResponse response,
								  String cookieName, String cookieValues, Integer cookieLifeTime) {
		Cookie cookie = new Cookie(cookieName, cookieValues);
		cookie.setMaxAge(cookieLifeTime);//设置cookie的存活时间
		cookie.setPath(request.getServletContext().getContextPath());//
		response.addCookie(cookie);//保存cookie
	}

}
